<template>
  <el-input
    ref="inputRef"
    v-model="formattedValue"
    :input-style="{ textAlign }"
    @change="handleChange"
    @clear="handleClear"
  >
    <template v-if="currency" #prefix>{{ handleCType }}</template>
    <template v-else-if="prefix" #prefix>{{ prefix }}</template>
    <template v-else-if="suffix" #suffix>{{ suffix }}</template>
  </el-input>
</template>
<script setup>
import { computed, watch } from 'vue'
import { useCurrencyInput } from 'vue-currency-input'
const props = defineProps({
  modelValue: [Number, String],
  // 常用货币类型：CNY，EUR，USD，JPY 等
  currency: {
    type: String,
    default: ''
  },
  // 精度
  precision: {
    type: Number,
    default: 2
  },
  // 最小值
  min: {
    type: Number
  },
  // 最大值
  max: {
    type: Number
  },
  // 是否默认分隔 如千分位
  useGrouping: {
    type: Boolean,
    default: true
  },
  // symbol: 如US$100, narrowSymbol: 如￥100, code: 如CNY100, name: 如100美元, hidden: 如隐藏符号
  // 此处 设置为 hidden，采用自定义符号
  currencyDisplay: {
    type: String,
    default: 'hidden'
  },
  // 自定义头部内容
  prefix: {
    type: String,
    default: ''
  },
  // 自定义尾部内容
  suffix: {
    type: String,
    default: ''
  },
  // 文本对齐
  textAlign: {
    type: String,
    default: 'right'
  }
})
const emit = defineEmits(['update:modelValue', 'change'])
const options = computed(() => {
  return {
    currency: props.currency || 'CNY',
    precision: props.precision,
    valueRange: { min: props.min, max: props.max },
    useGrouping: props.useGrouping,
    currencyDisplay: props.currencyDisplay
  }
})

// 常用货币
const handleCType = computed(() => {
  let type
  const cTypes = [
    { key: 'CNY', value: '¥' },
    { key: 'EUR', value: '€' },
    { key: 'USD', value: '$' },
    { key: 'GBP', value: '£' },
    { key: 'JPY', value: '¥' }
  ]
  cTypes.forEach((item) => {
    if (item.key === props.currency) {
      type = item.value
    }
  })
  return type
})
// By default, the number value is automatically emitted on each input. This can be disabled by setting the autoEmit argument of useCurrencyInput to false, allowing you to implement a custom emit behavior for features such as debouncing.
const { inputRef, formattedValue, numberValue, setOptions, setValue } = useCurrencyInput(options.value, false)

const handleChange = (val) => {
  setOptions(options.value)
  if (!val) {
    setValue(0)
    emit('update:modelValue', 0)
    emit('change', 0)
  } else {
    emit('update:modelValue', numberValue.value)
    emit('change', numberValue.value)
  }
}
const handleClear = () => {
  setValue(0)
}
const init = () => {
  if (!props.modelValue) {
    emit('update:modelValue', 0)
  } else {
    if (props.min && props.min > Number(props.modelValue)) {
      emit('update:modelValue', props.min)
    } else if (props.max && props.max < Number(props.modelValue)) {
      emit('update:modelValue', props.max)
    } else {
      emit('update:modelValue', Number(props.modelValue))
    }
  }
}
watch(
  () => props.modelValue,
  (value) => {
    if (value) {
      setValue(value)
    } else {
      setValue(0)
    }
  },
  { immediate: true }
)
watch(
  () => options.value,
  (options) => {
    setOptions(options)
  },
  { deep: true, immediate: true }
)

init()
</script>
<style scoped lang="scss">
:deep(.el-input__inner) {
  text-align: right;
}
</style>
